﻿package
{
	import fl.transitions.*;
	import fl.transitions.easing.*;
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.display.Shape;
	import flash.text.TextField;
	
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	
	import flash.external.ExternalInterface;
	
	
	/**
	 * Esta clase es la encargada de controlar el escenario de juego,
	 * asi como todos sus elementos que lo integran, vectores, personaje, y botones
	 * de acccion de la interfaz grafica
	 * 
	 * @author ... STEVENS PINEDA, GERMAN CAÑON, SEBASTIAN GONZALES
	 */
	public class Escenario extends MovieClip
	{
		//@PRIVATE
		private const ANCHO:int = 900
		private const ALTO:int = 700
		
		//Estas variables permiten controlar el movimiento del peronaje tanto
		//en su eje x como su eje y
		var mover:Tween;
		var mover2:Tween;
		
		//este array almacena los vectores que hay presentes en el escenario
		private var mosquitos:Array
		private var personas:Array
		public var personaje:Personaje
		
		//Representa el vector seleccionado por el usuario
		public var persona_select:Persona
		public var mosco_select:Mosquito
		
		//@PRIVATE
		public var vidaPersonaje:BarraNivel;
		public var onda:MovieClip;
		
		//public var select_p:Objetivo
		
		//array con los puntos de salidas para las personas
		public var salidas:Array = new Array(200, -100, 700, -100, -100, 200, -100, 500, 1000, 200, 1000, 500);
		
		public var bonusActual:int = 0
		
		//Temporizadores para las acciones del jeugo
		private var timer:Timer;
		private var timerAyuda:Timer;
		private var timerBonus:Timer;
		private var timerJuego:Timer;
		
		//Variables para controlar el tiempo transcurrido
		private var segundos:Number = 0
		private var minutos:Number = 0
		
		//@PRIVATE
		private var bordeBarra:Shape;
		
		//Variables para controlar las herramientas del personaje
		public var numMedicinas:int
		public var numInsecticida:int
		
		//@PRIVATE
		public var btnMedicina:SimpleButton
		public var btnInsecticida:SimpleButton
		
		//@PRIVATE
		public var textTime:TextField;
		
		//@PRIVATE
		public var termina:Boolean = false
		public var ganar:Boolean = false
		
		//@PRIVATE
		public var mosquitosMuertos:int
		
		//@PRIVATE
		private var intro:MaquinaSuave = new MaquinaSuave();
		private var sound:LanzarM = new LanzarM();
		private var soundBonus:Crear = new Crear();
		private var idAyuda:int =0
		
		/**
		 * Este es al constructor de la aplicacion, donde se inicializa el personaje y los vectores
		 * tambien se inician los temporizadores para realizar las distintas acciones
		 */
		public function Escenario()
		{
			intro.play(0, 200)
			
			timerAyuda = new Timer(10000, 0)
			timerAyuda.addEventListener(TimerEvent.TIMER, ayuda);
			timerAyuda.start()

			infoIntro.ayuda.gotoAndStop(0)
			infoIntro.btnJugar.addEventListener(MouseEvent.CLICK, iniciar)
			
		}
		
		/**
		 * Este metodo inicia el ciclo del juego
		 * @param	e target que llamo la funcion inicar
		 */
		private function iniciar(e:MouseEvent):void 
		{
			infoIntro.visible=false
			init()
		}
		
		/**
		 * Este metodo inicia todos los componentes del escenario
		 * tanto personajes, como vectores, y los eventos asociados
		 * a cada uno de los elementos de la interfaz
		 */
		public function init() {
			
			//@private
			vidaPersonaje = new BarraNivel(100)
			personaje = new Personaje(450, 500, vidaPersonaje, this)
			
			//@private
			vidaPersonaje.x = 105
			vidaPersonaje.y = 660
			vidaPersonaje.width = 600
			vidaPersonaje.height = 20
			
			//@private
			bordeBarra = new Shape();
			bordeBarra.graphics.lineStyle(2, 0)
			bordeBarra.graphics.drawRect(105, 660, 600, 20)
			
			//@private
			this.addChild(vidaPersonaje)
			this.addChild(bordeBarra)
			
			//@private
			textTime = this.textTime
			btnMedicina = this.btnMedicina
			btnInsecticida = this.btnInsecticida
			
			//@private
			onda = this.onda
			
			//@private
			timer = new Timer(1000, 0)
			
			//@private
			timerBonus = new Timer(8000, 0)
			timerJuego = new Timer(2000, 0)
			
			//@private
			numInsecticida = 5
			numMedicinas = 6
			
			//Añadimos los vectores al escenario
			addMosquitos()
			addPersonas()
			//iniciamos la interaccion de los vectores
			moverMosquitos()
			moverPersonas()
			//detenemos las acciones del personaje
			pararMuneco();
			
			//@private
			this.addChild(personaje)
			
			//@private
			segundos = 0
			minutos = 0
			
			//@private
			setTime()
			
			//actualiza la informacion de la pantalla
			actualizaInfo()
			
			//añadimos los listeners de las acciones del usuario
			btnMedicina.addEventListener(MouseEvent.CLICK, clicMedicina)
			btnInsecticida.addEventListener(MouseEvent.CLICK, clicInsecticida)
			boxMensaje.btnAceptar.addEventListener(MouseEvent.CLICK, reinicia)
			
			stage.addEventListener(MouseEvent.CLICK, clicOnArea);
			
			timer.addEventListener(TimerEvent.TIMER, contar);
			timerBonus.addEventListener(TimerEvent.TIMER, bonus);
			timerJuego.addEventListener(TimerEvent.TIMER, loopJuego);
			
			//inicia los temporizadores
			timer.start()
			timerBonus.start()
			timerJuego.start()
			
			//@private
			item1.visible = false
			item2.visible = false
			boxMensaje.visible=false
			
			//@private
			mosquitosMuertos = 0
			termina = false
			ganar = false
		}
		
		/**
		 * Controla las acciones del contenedor de la ayuda de usuario
		 * automatizadamente
		 * @param	e target que llamo la funcion inicar
		 */
		private function ayuda(e:TimerEvent):void 
		{
			if (idAyuda > 2) idAyuda = -1

			idAyuda++
			infoIntro.ayuda.gotoAndStop(idAyuda+1)
			
		}
		
		/**
		 * Este metodo remueve los vectores y personas
		 * que hay en el escenario para reinicar el jeugo
		 * 
		 */
		public function removerElementos() {
			
			for (var i:int = 0; i < personas.length; i++){
				removeChild(personas[i])
			}
			
			for (var j:int = 0; j < mosquitos.length; j++){
				removeChild(mosquitos[j])
			}
			
		}
		
		/**
		 * Este metodo reinicia el ciclo del juego
		 * @param	e target que llamo la funcion reiniciar
		 */
		private function reinicia(e:MouseEvent):void 
		{
			init()
			
			var loader:URLLoader = new URLLoader();
			var peticion:URLRequest = new URLRequest("http://ethgf.com/nt_den/php/post_wall.php?time=" + txtTime.text);
			
			loader.load(peticion);

		}
		
		/**
		 * Este metodo incrementa el contador de los vectores
		 * eliminados en el escenario
		 */
		public function addMosquitosMuertos() {
			mosquitosMuertos++
		}
		
		/**
		 * Este controla el ciclo del juego para tomar las deciciones
		 * logicas de acuerdo a su desarrollo
		 * @param	e target que llamo la funcion loopJuego
		 */
		private function loopJuego(e:TimerEvent):void 
		{

			if ( mosquitosMuertos >= mosquitos.length) {
				termina = true
				ganar = true
			}
			
			if (termina) {
				finalizaJuego()
			}
		}
		
		/**
		 * Este metodo finaliza el juego determinando si ha ganado o
		 * perdido la partida
		 */
		private function finalizaJuego():void 
		{
			
			for (var i:int = 0; i < personas.length; i++) {
				
				personas[i].visible = false
				personas[i].nivel.visible = false
			}
				
			for (var j:int = 0; j < mosquitos.length; j++) {
				
				mosquitos[j].nivel.visible = false
				mosquitos[j].visible = false
			}
			
			item1.visible = false
			item2.visible = false
			
			mosquitosMuertos = 0
			
			personaje.visible = false
			
			select.visible = false
			select_m.visible = false
			select_p.visible = false
			
			timer.stop()
			timerBonus.stop()
			timerJuego.stop()
			boxMensaje.visible = true
			flagSelected = true
			persona_select = null
			mosco_select = null
			mover.stop()
			mover2.stop()
			
			if (ganar) boxMensaje.txtInfo.text = "HAS GANADO"
			else boxMensaje.txtInfo.text = "HAS PERDIDO"
			
			boxMensaje.txtTiempo.text= "Tiempo: " + txtTime.text
			
		}
		
		/**
		 * Este metodo genera aleatoriamente un bonus para el usuario
		 * para tomar como ventaja con el ataque a vectores
		 * @param	e target que llamo la funcion bonus
		 */
		private function bonus(e:TimerEvent):void
		{
			var aleatorio:int = Math.round(Math.random() * 2) + 1
			
			var xA:int = Math.round(Math.random() * 800);
			var yA:int = Math.round(Math.random() * 500);
			
			yA += 50
			xA += 50
			
			timerBonus.stop()
			
			var timerTem:Timer = new Timer(5000, 1)
			
			timerTem.start()
			timerTem.addEventListener(TimerEvent.TIMER, hideBonus)
			
			switch (aleatorio)
			{
				case 1: 
					item1.x = xA
					item1.y = yA
					item1.visible = true
					item2.visible = false
					break;
				case 2: 
				case 3:
				case 4:
					item2.x = xA
					item2.y = yA
					item2.visible = true
					item1.visible = false
					break;
			}
		
		}
		
		/**
		 * Oculata el bonus seleccionado
		 * e targ<cet que llamo la funcion hideBonus
		 */
		private function hideBonus(e:TimerEvent):void
		{
			item1.visible = false
			item2.visible = false
			timerBonus.start()
		}
	
		/**
		 * Aplica un insecticida a los vectores que comparten un radio de 3 mts
		 * con el personaje
		 * e targ<cet que llamo la funcion clicInsecticida
		 */
		private function clicInsecticida(e:MouseEvent):void
		{
			if (numInsecticida > 0 && !termina)
			{
				sound.play(0,1)
				for (var i:int = 0; i < mosquitos.length; i++)
				{
					
					var distancia:int = Math.round(Math.sqrt((mosquitos[i].x - personaje.x) * (mosquitos[i].x - personaje.x) + (mosquitos[i].y - personaje.y) * (mosquitos[i].y - personaje.y)))
					
					if (distancia <= 250)
					{
						(BarraNivel)(mosquitos[i].nivel).addEstado(-18)
					}
				}
				
				onda2.x = personaje.x
				onda2.y = personaje.y
				onda2.gotoAndPlay(0);
				
				numInsecticida--
				actualizaInfo()
			}
		}
		
		/**
		 * Aplica una medicina a las personas que comparten un radio de 3 mts
		 * con el personaje
		 * e targ<cet que llamo la funcion clicMedicina
		 */
		private function clicMedicina(e:MouseEvent):void
		{
			
			if (numMedicinas > 0 && !termina)
			{
				sound.play(0,1)
				for (var i:int = 0; i < personas.length; i++)
				{
					
					var distancia:int = Math.round(Math.sqrt((personas[i].x - personaje.x) * (personas[i].x - personaje.x) + (personas[i].y - personaje.y) * (personas[i].y - personaje.y)))
					
					if (distancia <= 200)
					{
						(BarraNivel)(personas[i].nivel).addEstado(8)
					}
				}
				
				onda.x = personaje.x
				onda.y = personaje.y
				onda.gotoAndPlay(0);
				
				numMedicinas--
				actualizaInfo()
			}
		}
		
		/**
		 * Actualiza la informacion de pantalla del usuario
		 * con los datos del juego
		 */
		private function actualizaInfo():void
		{
			txtNumInsecticida.text = "x" + numInsecticida
			txtNumMedicina.text = "x" + numMedicinas
		}
		
		/**
		 * Actualiza la informacion del contador de pantalla del juego
		 * 
		 */
		public function setTime()
		{
			
			var minS:String = ""
			var segS:String = ""
			
			if (minutos < 10)
				minS = "0"
			else
				minS = ""
			
			minS += minutos
			
			if (segundos < 10)
				segS = "0"
			else
				segS = ""
			
			segS += segundos
			
			txtTime.text = minS + ":" + segS + ""
		
		}
		
		/**
		 * Actualiza el contador del tiemoo
		 * de pantalla
		 */
		private function contar(e:TimerEvent):void
		{
			segundos++
			
			if (segundos > 59)
			{
				segundos = 0
				minutos++
			}
			setTime()
		}
		
		/*
		 * Este es el metodo encargar de detener las acciones del personaje
		 * */
		private function termino(e:TweenEvent)
		{
			pararMuneco();
		}
		
		/*
		 * Este metodo es el encargado de controlar las acciones del movimiento del
		 * personaje, cuando se hace click sobre cualquier zona del escenario
		 *
		 */
		
		var flagSelected:Boolean = false
		
		private function clicOnArea(e:MouseEvent):void
		{
			if (mouseY < 620)
			{
				
				for (var i:int = 0; i < personas.length; i++)
				{
					
					if (mouseX > (personas[i].x - personas[i].width / 2) && mouseX < (personas[i].x + personas[i].width / 2) && mouseY > (personas[i].y - personas[i].height / 2) && mouseY < (personas[i].y + personas[i].height / 2))
					{
						
						persona_select = personas[i]
						
						select_p.x = persona_select.x - (persona_select.width / 2)
						select_p.y = persona_select.y - (persona_select.height / 2)
						
						return;
					}
				}
				
				for (var j:int = 0; j < mosquitos.length; j++)
				{
					
					if (mouseX > (mosquitos[j].x - mosquitos[j].width / 2) && mouseX < (mosquitos[j].x + mosquitos[j].width / 2) && mouseY > (mosquitos[j].y - mosquitos[j].height / 2) && mouseY < (mosquitos[j].y + mosquitos[j].height / 2))
					{
						
						mosco_select = mosquitos[j]
						
						flagSelected = true
						return;
					}
					flagSelected = false
				}
				
				//mover el personaje
				if (!flagSelected)
				{
					
					select.x = mouseX - select.width / 2
					select.y = mouseY - select.height / 2
					personaje.rotation = (180 * Math.atan2(mouseY - personaje.y, mouseX - personaje.x)) / Math.PI + 90;
					
					if (mover != null)
						mover.removeEventListener(TweenEvent.MOTION_FINISH, termino);
					
					var dXY:Number = Math.sqrt(Math.pow(mouseX - personaje.x, 2) + Math.pow(mouseY - personaje.y, 2));
					
					var time:Number = dXY / 100;
					
					//Se mueve el personaje hacia las coordenadas seleciconadas por el usuario
					mover = new Tween(personaje, "x", null, personaje.x, mouseX, time, true);
					mover2 = new Tween(personaje, "y", null, personaje.y, mouseY, time, true);
					
					mover.start();
					mover2.start();
					
					personaje.play();
					
					mover.addEventListener(TweenEvent.MOTION_FINISH, termino);
					mover.addEventListener(TweenEvent.MOTION_CHANGE, hayBonus);
				}
			}
		}
		
		/**
		 * Este metodo se encarga de comprobar si el personaje ah recogido un bonus del escenario
		 * para tomarlo como ventajas
		 * 
		 * @param e origen del evento
		 */
		private function hayBonus(e:Event):void
		{
			var mcBonus:MovieClip = null
			var estado:int = 0
			
			if (item1.visible)
			{
				mcBonus = item1
				estado = 1
			}
			if (item2.visible)
			{
				mcBonus = item2
				estado = 2
			}
			
			if (mcBonus != null)
			{
				if (personaje.x > mcBonus.x && personaje.x < (mcBonus.x + 50) && personaje.y > mcBonus.y && personaje.y < (mcBonus.y + 50))
				{
					mcBonus.visible = false
					
					if (estado == 1){
						numMedicinas += 2
						soundBonus.play(0,1)
					}
					if (estado == 2){
						numInsecticida += 2
						soundBonus.play(0,1)
					}
					
					actualizaInfo()
				}
			}
		}
		
		/*
		 * Este metodo es el encargado de añadir los vectores al escenario
		 * en las zonas infectadas por el virs del dengue
		 * */
		private function addMosquitos()
		{
			//if(mosquitos == null){
				mosquitos = new Array()
				
				//Agregamos los mosquitos de la zona 1
				for (var i:int = 0; i < 5; i++)
				{
					
					var nivel:BarraNivel = new BarraNivel(75);
					
					var mosquito:Mosquito = new Mosquito(80, 50, 500, 460, nivel, this)
					mosquito.name ="mosquito"
					
					mosquitos.push(mosquito)
					this.addChild(mosquito)
					this.addChild(nivel)
				}
				
				//Agregamos los mosquitos de la zona 1
				for (var j:int = 0; j < 5; j++)
				{
					var nivel2:BarraNivel = new BarraNivel(75);
					
					var mosquito2:Mosquito = new Mosquito(530, 200, 800, 500, nivel2, this)
					mosquito.name = "actor"
					
					mosquitos.push(mosquito2)
					this.addChild(mosquito2)
					this.addChild(nivel2)
				}
		}
		
		/**
		 * Metodo encargado de agregar las personas al escenario
		 * e iniciar su movimientos
		 */
		private function addPersonas()
		{
			
			personas = new Array()
			
			//Agregamos las personas
			for (var i:int = 0; i < 5; i++)
			{
				
				var nivel:BarraNivel = new BarraNivel(100);
				var num:int = Math.round(Math.random() * 6) * 2
				
				var x:int = salidas[num]
				var y:int = salidas[num + 1]
				var persona:Persona = new Persona(20, 20, width - 20, height - 20, x, y, nivel, this)
				
				persona.name ="actor"
				
				personas.push(persona)
				this.addChild(persona)
				this.addChild(nivel)
			}
		
		}
		
		/*
		 * Este es el metodo ecargado de iniciar el movimiento de los vectores
		 * */
		private function moverMosquitos()
		{
			
			for (var i:int; i < mosquitos.length; i++)
				mosquitos[i].run()
		}
		
		private function moverPersonas()
		{
			
			for (var i:int; i < personas.length; i++)
				personas[i].run()
		}
		
		/*
		 *Este es el metodo encargado de detener las las acciones del personaje
		 * */
		private function pararMuneco():void
		{
			personaje.gotoAndStop(1);
		}
		
		public function getAncho():int
		{
			return ANCHO;
		}
		
		public function getAlto():int
		{
			return ALTO;
		}
		
		public function getMosquitos():Array
		{
			return mosquitos;
		}
		
		public function getPersonas():Array
		{
			return personas;
		}
	
	}
}